/**
 * @用法
 * vite打包完成后，使用命令行nodejs执行本文件: node obfuscator.js
 * 它会挨个把里面的js文件做混淆然后替换
 * 
 * @说明
 * 本质就是依赖这个工具
 * 底层实现就是把代码全部作为一个字符串丢给它，它内部调用其他包来分析语法，做混淆替换
 * 
 * @doc https://github.com/javascript-obfuscator/javascript-obfuscator
 * 
 * @拓展
 * obfuscator.js也有对应 webpack 的 plugin 和 rollup（vite打包用的就是rollup） 的 plugin
 * 实现起来比较简单，如有需要也可以自己找符合要求的plugin或者自己写一个，本质上就是把这个文件的执行过程自动追加到打包过程中
 */
const JavaScriptObfuscator = require('javascript-obfuscator')
const fs = require('fs')

// 配置
const buildDir = './dist/assets/'

/**
 * 获取目录下所有js文件及内容字符串
 * @result {fileName:string, content:string}[]
 */
const getJsFileList = (dir) => new Promise((resolve) => {
	fs.readdir(dir, (err, files) => {
		if (err) return reject(`[obfuscator] output dir not exist!`)

		return resolve(Promise.all(files.filter(fileName => fileName.endsWith('.js')).map(fileName => new Promise(resolveInner => {
			fs.readFile(dir + fileName, (err, data) => {
				return resolveInner({ fileName, content: data.toString() })
			})
		}))))
	})
})

getJsFileList(buildDir).then(list => {
	console.log(`[obfuscator] start`)
	Promise.all(list.map(it => new Promise(resolve => {
		const obfuscationResult = JavaScriptObfuscator.obfuscate(it.content, {
			/** 这些都是配置 */
			compact: false,
			controlFlowFlattening: true,
			controlFlowFlatteningThreshold: 1,
			numbersToExpressions: true,
			simplify: true,
			stringArrayShuffle: true,
			splitStrings: true,
			stringArrayThreshold: 1
		})
		fs.writeFile(buildDir + it.fileName, obfuscationResult.getObfuscatedCode(), () => {
			console.log(`[obfuscator] file done ${it.fileName}`)
			resolve(1)
		})
	}))).then(() => {
		console.log(`[obfuscator] finished`)
	})
})